import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
import requests
import cv2
from selenium.webdriver.common.keys import Keys
import numpy
from MachineLearning.getTag import get_tag
from selenium.webdriver import ChromeOptions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.options import Options

class KuGouMusic:
    def __init__(self,PhoneNum):
        """
        self.path_of_Searchinput:搜索框的位置
        self.path_of_MusicList:进入下一页面后选择搜索歌单
        self.path_of_ExplicitMusicList_l:歌单列表，每个歌单的位置的左半部分
        self.path_of_ExplicitMusicList_r:歌单列表，每个歌单的位置的右半部分
        self.path_of_PlayButton:开始播放的按钮
        self.path_of_StopButton:停止播放的按钮
        self.path_of_ContinueButton:继续播放的按钮
        self.Play_Circle:用于暂停继续的循环的参数
        """
        # # 设置options参数，以开发者模式运行
        # self.option = ChromeOptions()
        # self.option.add_experimental_option("excludeSwitches", ["enable-automation"])
        #
        # # 解决报错，设置无界面运行
        # self.option.add_argument('--no-sandbox')
        # self.option.add_argument('--disable-dev-shm-usage')
        # self.option.add_argument('window-size=1920x3000')  # 指定浏览器分辨率
        # self.option.add_argument('--disable-gpu')  # 谷歌文档提到需要加上这个属性来规避bug
        # self.option.add_argument('--hide-scrollbars')  # 隐藏滚动条, 应对一些特殊页面
        # self.option.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片, 提升速度
        # self.option.add_argument('--headless')  # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
        self.driver = webdriver.Chrome()
        self.driver.set_window_position(0,0)
        self.driver.set_window_size(600,600)
        self.driver.get("https://www.kugou.com/")
        self.phoneNum = PhoneNum
        self.tag_list = {0:"蓝调",1:"宁静",2:"活力"}
        self.path_of_Searchinput = "/html/body/div[1]/div[1]/div/div[1]/div/input"
        self.path_of_MusicList = "/html/body/div[4]/ul/li[2]/a"
        self.path_of_ExplicitMusicList_l = "/html/body/div[4]/div[2]/div[2]/ul[2]/li["
        self.path_of_ExplicitMusicList_r = "]/div[1]/a[2]"
        self.path_of_PlayButton = "/html/body/div[3]/div[3]/div[1]/h4/a/span/i"
        self.path_of_StopButton = "/html/body/div[1]/div[4]/div[2]/div[1]/a[2]"
        self.path_of_ContinueButton = "/html/body/div[1]/div[4]/div[2]/div[1]/a[2]"
        self.path_of_phoneNumValidation = "/html/body/div[1]/div[3]/div[2]/form/div[2]/div/input"
        self.path_of_FinallLogin = "/html/body/div[1]/div[3]/div[2]/form/div[4]/div/div/input"
        self.path_of_musicName = "/html/body/div[1]/div[3]/div[1]/div[2]/div[1]/span"
        self.path_of_musicCover = "/html/body/div[1]/div[3]/div[1]/div[1]/div[1]/a/img"
        self.Play_Circle = 0

    def Login(self):
        self.driver.find_element(By.XPATH,"/html/body/div[1]/div[1]/div/div[2]/div[2]/div[1]").click() #点击登录
        self.driver.implicitly_wait(3)
        frame1 = self.driver.find_element(By.XPATH,"/html/body/div[4]/iframe")
        self.driver.switch_to.frame(frame1)
        self.driver.find_element(By.XPATH,"/html/body/div[1]/div[1]").click() #切换至密码登录
        self.driver.implicitly_wait(3)
        self.driver.find_element(By.XPATH,"/html/body/div[1]/div[3]/div[2]/form/div[1]/div/input").send_keys(self.phoneNum)
        self.driver.find_element(By.XPATH,"/html/body/div[1]/div[3]/div[2]/form/div[2]/div/a").click()  #点击发送验证码
        self.validation()
        self.driver.minimize_window()

    def tran_canny(self,image):
        """消除噪声"""
        image = cv2.GaussianBlur(image, (3, 3), 0)
        return cv2.Canny(image, 50, 150)

    def detect_displacement(self,img_slider_path, image_background_path):
        """detect displacement"""
        # # 参数0是灰度模式
        image = cv2.imread(img_slider_path, 0)
        template = cv2.imread(image_background_path, 0)

        # 寻找最佳匹配
        res = cv2.matchTemplate(self.tran_canny(image), self.tran_canny(template), cv2.TM_CCOEFF_NORMED)
        # 最小值，最大值，并得到最小值, 最大值的索引
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

        top_left = max_loc[0]  # 横坐标
        # 展示圈出来的区域
        x, y = max_loc  # 获取x,y位置坐标

        w, h = image.shape[::-1]  # 宽高
        cv2.rectangle(template, (x, y), (x + w, y + h), (7, 249, 151), 2)
        return top_left

    #验证码破解
    def validation(self):
        frame = self.driver.find_element(By.XPATH,"/html/body/div[6]/iframe")
        self.driver.switch_to.frame(frame)
        button = self.driver.find_element(By.XPATH,"/html/body/div/div[3]/div[2]/div[2]/div[2]")
        image1 = self.driver.find_element(By.XPATH,"/html/body/div/div[3]/div[2]/div[1]/div[2]/img")
        image2 = self.driver.find_element(By.XPATH,"/html/body/div/div[3]/div[2]/div[1]/div[3]/img")
        #把两张图爬下来
        image1_src = image1.get_attribute("src")
        data1 = requests.get(image1_src)
        with open("./MusicPlayer/tmp/bg.png","wb") as f:
            f.write(data1.content)

        image2_src = image2.get_attribute("src")
        data2 = requests.get(image2_src)
        with open("./MusicPlayer/tmp/front.png","wb") as f:
            f.write(data2.content)

        down_width = 340
        down_height = 195
        down_points = (down_width, down_height)
        image = cv2.imread("./MusicPlayer/tmp/bg.png")
        resized_down = cv2.resize(image, down_points, interpolation=cv2.INTER_LINEAR)
        cv2.imwrite("/MusicPlayer/tmp/bg.png",resized_down)

        down_width = 68
        down_height = 68
        down_points = (down_width, down_height)
        image = cv2.imread("./MusicPlayer/tmp/front.png")
        resized_down = cv2.resize(image, down_points, interpolation=cv2.INTER_LINEAR)
        cv2.imwrite("./MusicPlayer/tmp/front.png", resized_down)

        distance = self.detect_displacement("./MusicPlayer/tmp/front.png","./MusicPlayer/tmp/bg.png") - 28

        #移动轨迹
        # 移动轨迹
        track = []
        # 当前位移
        current = 0
        # 减速阈值
        mid = distance * 4 / 5
        # 计算间隔
        t = 0.3  # 时间越大误差越大
        # 初速度
        v = 0
        while current < distance:
            if current < mid:
                # 加速度为正2
                a = 2
            else:
                # 加速度为负3
                a = -3
            # 初速度v0
            v0 = v
            # 当前速度v = v0 + at
            v = v0 + a * t
            # 移动距离x = v0t + 1/2 * a * t^2
            move = v0 * t + 1 / 2 * a * t * t
            # 当前位移
            current += move
            # 加入轨迹
            track.append(round(move))  # 四舍五入
        print("位移" + str(current))

        ActionChains(self.driver).click_and_hold(button).perform()  # 按住滑块
        for x in track:
            ActionChains(self.driver).move_by_offset(xoffset=x, yoffset=0).perform()  # 进行水平移动y=0
        time.sleep(0.5)
        ActionChains(self.driver).release().perform()  # 松开滑块
        return None

    def search_type(self,tag):
        first_window = self.driver.window_handles[0]
        self.driver.switch_to.window(first_window)
        self.driver.minimize_window()
        type_music = self.tag_list[tag]
        input_Tag = self.driver.find_element(By.XPATH,self.path_of_Searchinput)
        input_Tag.send_keys(type_music)
        input_Tag.send_keys(Keys.ENTER)
        self.driver.find_element(By.XPATH,self.path_of_MusicList).click()

    def get_music(self):
        time.sleep(0.5)
        num = numpy.random.randint(1,20)
        print(num)
        num = str(num)
        path = self.path_of_ExplicitMusicList_l+num+self.path_of_ExplicitMusicList_r
        self.driver.find_element(By.XPATH,path).click()
        # 找出新窗口：
        new_window = self.driver.window_handles[-1]
        # 切换到新窗口：
        self.driver.switch_to.window(new_window)
        self.driver.find_element(By.XPATH,self.path_of_PlayButton).click()
        # 找出新窗口：
        new_window = self.driver.window_handles[-1]
        # 切换到新窗口：
        self.driver.switch_to.window(new_window)
        #删去弹窗
        self.driver.implicitly_wait(2)
        button = self.driver.find_element(By.XPATH,"/html/body/div[4]/div/table/tbody/tr[1]/td/button")
        self.driver.execute_script('arguments[0].click()', button)
        self.driver.minimize_window()
        music_name = self.driver.find_element(By.XPATH,self.path_of_musicName).get_attribute("title")
        print(music_name)
        music_cover = self.driver.find_element(By.XPATH,self.path_of_musicCover).get_attribute("src")
        data3 = requests.get(music_cover)
        with open("./MusicPlayer/tmp/music_cover.jpg","wb") as f:
            f.write(data3.content)

        #暂停
    def Stop(self):
        button = self.driver.find_element(By.XPATH,self.path_of_StopButton)
        button.click()
        print("已暂停")
        self.Play_Circle +=1

    def quit(self):
        self.driver.quit()


    def Continue(self):
        if self.Play_Circle % 2 == 1:
            button = self.driver.find_element(By.XPATH,self.path_of_ContinueButton)
            button.click()
            self.Play_Circle += 1
        else:
            print("未被暂停")

    def input_validationNum(self,num):
        self.driver.find_element(By.XPATH,self.path_of_phoneNumValidation).send_keys(num)
        self.driver.find_element(By.XPATH,self.path_of_FinallLogin).click()

if __name__ == "__main__":
    Player = KuGouMusic("13243254221")
    Player.Login()
    Player.search_type(0)
    Player.get_music()
